/*
 * @Descripttion: 
 * @version: 
 * @Author: 周志伟
 * @Date: 2021-06-07 15:05:36
 * @LastEditors: 周志伟
 * @LastEditTime: 2021-06-11 19:30:55
 */
'use strict';
var FS = require("fire-fs"), PATH = require("fire-path"), fse = require("fs-extra");
const Path = require('path');

var FileUtil = require('./utils/file-util');
var ObjectUtil = require('./utils/object-util');
module.exports = {
  /**
   * 节点树缓存
   * @type {{ [key: string]: object }}
   */
  cache: Object.create(null),
  load() {
    // execute when package loaded
  },

  unload() {
    this.cache = null;
    // execute when package unloaded
  },

  // register your ipc messages here
  messages: {
    /**
    * 打开 全局查找面板
    */
    'open-global—find-panel'() {
      Editor.log('打开 全局查找面板');
      Editor.Panel.open(`zzw_quate.global`);
    },

    /**
     * 打开局部预制查找面板
     */
    'open-partial-find-panel'() {
      Editor.log('打开局部预制查找面板');
      Editor.Panel.open(`zzw_quate.partial`);
    },
    'find-global-quate'() {
      Editor.log("zzzzzz")
    },
    'find-partial-quate'(event, uuid) {
      Editor.log('局部预制查找开始', uuid);
      this.findViaUuid(uuid);
    },
  },

  findViaUuid(uuid) {
    // 获取资源信息
    const assetInfo = Editor.assetdb.assetInfoByUuid(uuid);
    let jsonInfo1 = FS.readJsonSync(assetInfo.path);
    let jsonInfo = this.assetDecompressUuid(jsonInfo1);
    let uuidArr = ObjectUtil.containsProperty(jsonInfo, '__uuid__', '_materials');
    let bundleName = this.getBundleNameByUuid(uuid);
    let resultArr = this.checkIsExistUuidArr(uuidArr, bundleName);
    this.printResult(resultArr, bundleName);
    const nodeTree = this.getNodeTree(assetInfo.path);
    Editor.log("zz", nodeTree);
  },
  /**
   * 将预制文件中是脚本的的type属性转换成uuid
   * @param {} jsonInfo 
   */
  assetDecompressUuid(jsonInfo) {
    let len = jsonInfo.length;
    for (let i = 0; i < len; i++) {
      let str = jsonInfo[i].__type__;
      let str1 = Editor.Utils.UuidUtils.decompressUuid(jsonInfo[i].__type__, false);
      if (str1 != str) {
        jsonInfo[i].__uuid__ = str1;
      }
    }
    return jsonInfo;
  },
  /**
   * 打印结果
   * @param {} resultArr 
   * @param {} bundleName 当前bundle的名称
   */
  printResult(resultArr, bundleName) {
    if (resultArr && resultArr.length > 0) {
      Editor.error("****************************以下资源不在***" + bundleName + "***bundle里****************************");
      for (let i = 0; i < resultArr.length; i++) {
        Editor.error(resultArr[i]);
      }
      Editor.error("****************************以上资源不在***" + bundleName + "***bundle里****************************");
    } else {
      Editor.log("****************************" + bundleName + "下的预制体正常****************************");
    }
  },
  /**
   * 检测容器中的uuid是否都在改bundle下
   * @param {*} uuidArr 存放uuid的容器
   * @param {*} bundleName   
   * @returns 
   */
  checkIsExistUuidArr(uuidArr, bundleName) {
    let resultArr = [];
    for (let i = 0; i < uuidArr.length; i++) {
      let assetInfo = Editor.assetdb.assetInfoByUuid(uuidArr[i]);
      let _path = assetInfo.path;
      let str1 = "assets\\" + bundleName;
      let str2 = "assets\\resources";
      let str3 = "assets\\common";
      if (_path.indexOf(str1) == -1 && _path.indexOf(str2) == -1 && _path.indexOf(str3) == -1) {
        resultArr.push(_path);
      }
      // let yinyong = this.findReferences(uuidArr[i]);
      // Editor.log('zzzz', yinyong);
    }

    return resultArr;
  },
  /**
  * 查找引用
  * @param {string} uuid 
  * @returns {object[]}
  */
  findReferences(uuid) {
    const results = [];
    /**
     * 文件处理函数
     * @param {string} filePath 文件路径
     * @param {Fs.Stats} stats 
     */
    const searchHandler = (filePath, stats) => {
      const extname = Path.extname(filePath);
      // 场景和预制体资源
      if (extname === '.fire' || extname === '.prefab') {
        // 将资源数据转为节点树
        const nodeTree = this.getNodeTree(filePath),
          children = nodeTree.children,
          refs = [];
        // 遍历节点
        for (let i = 0, l = children.length; i < l; i++) {
          this.findRefsInNode(children[i], uuid, nodeTree, refs);
        }
        // 保存当前文件引用结果
        if (refs.length > 0) {
          results.push({
            type: typeMap[extname],
            fileUrl: Editor.assetdb.fspathToUrl(filePath),
            refs: refs
          });
        }
      }
      // 动画资源
      else if (extname === '.anim') {
        const data = JSON.parse(Fs.readFileSync(filePath)),
          curveData = data['curveData'],
          contains = ObjectUtil.containsValue(curveData, uuid);
        if (contains) {
          results.push({
            type: typeMap[extname],
            fileUrl: Editor.assetdb.fspathToUrl(filePath)
          });
        }
      }
      // 材质和字体资源
      else if (extname === '.mtl' || filePath.indexOf('.fnt.meta') !== -1) {
        const data = JSON.parse(Fs.readFileSync(filePath)),
          contains = ObjectUtil.containsValue(data, uuid);
        if (contains && !(data['uuid'] === uuid)) {
          const _extname = (extname === '.mtl') ? '.mtl' : '.fnt.meta';
          results.push({
            type: typeMap[_extname],
            fileUrl: Editor.assetdb.fspathToUrl(filePath)
          });
        }
      }
    };
    // 遍历资源目录下的文件
    const assetsPath = Editor.url('db://assets');
    FileUtil.map(assetsPath, searchHandler);
    // Done
    Editor.log('aaaaaaaa', results);
    return results;
  },
  /**
* 查找节点中的引用
* @param {object} node 目标节点
* @param {string} uuid 查找的 uuid
* @param {object} nodeTree 节点所在的节点树
* @param {object[]} container 结果容器
*/
  findRefsInNode(node, uuid, nodeTree, container) {
    // 检查节点上的组件是否有引用
    const components = node.components;
    if (components && components.length > 0) {
      for (let i = 0, l = components.length; i < l; i++) {
        const info = this.getContainsInfo(components[i], uuid);
        if (!info.contains) continue;
        // 资源类型
        let type = components[i]['__type__'];
        // 是否为脚本资源
        if (Editor.Utils.UuidUtils.isUuid(type)) {
          const scriptUuid = Editor.Utils.UuidUtils.decompressUuid(type),
            assetInfo = Editor.assetdb.assetInfoByUuid(scriptUuid);
          type = Path.basename(assetInfo.url);
        }
        // 处理属性名称
        let property = info.property;
        if (property) {
          // Label 组件需要特殊处理
          if (type === 'cc.Label' && property === '_N$file') {
            property = 'font';
          } else {
            // 去除属性名的前缀
            if (property.startsWith('_N$')) {
              property = property.replace('_N$', '');
            } else if (property[0] === '_') {
              property = property.substring(1);
            }
          }
        }
        // 保存结果
        container.push({
          node: node.path,
          component: type,
          property: property
        });
      }
    }
    // 检查预制体是否有引用
    const prefab = node.prefab;
    if (prefab) {
      // 排除预制体自己
      if (uuid !== nodeTree['__uuid__']) {
        const contains = ObjectUtil.containsValue(prefab, uuid);
        if (contains) {
          container.push({
            node: node.path
          });
        }
      }
    }
    // 遍历子节点
    const children = node.children;
    if (children && children.length > 0) {
      for (let i = 0, l = children.length; i < l; i++) {
        this.findRefsInNode(children[i], uuid, nodeTree, container);
      }
    }
  },
  /**
 * 获取节点树
 * @param {string} filePath 文件路径
 * @returns {object}
 */
  getNodeTree(filePath) {
    // 获取缓存
    let cache = this.cache;
    if (!cache) {
      cache = this.cache = Object.create(null);
    }
    // 从缓存中读取
    if (!cache[filePath]) {
      // 将资源数据转为节点树
      const data = JSON.parse(Fs.readFileSync(filePath));
      cache[filePath] = this.convertToNodeTree(data);
    }
    // Done
    return cache[filePath];
  },

  /**
   * 通过uuid获取所属的boundle名字
   * @param {} uuid 预制题uuid 
   */
  getBundleNameByUuid(uuid) {
    const assetInfo = Editor.assetdb.assetInfoByUuid(uuid);
    const urlItems = assetInfo.path.split("\\");
    let str = "";
    for (let i = 0; i < urlItems.length; i++) {
      if (urlItems[i - 1] == "assets") {
        str = urlItems[i];
        return str;
      }
    }
  },
  /**
   * 通过地址找到该资源下的所有uuid
   * @param {*} path 资源的地址
   */

  findAllUuidByPath(path) {
    var jsonInfo = FS.readdirSync(path)
    Editor.log('ssss', jsonInfo);

  },
  /**
   * 
   * @param {*} path 
   */
  findMetaByPath(path) {
    Editor.log("meta", path);
    let plistMetaPath = path + ".meta";
    let plistMetaStrings = FS.readFileSync(plistMetaPath, 'utf8');
    let plistMetaData = JSON.parse(plistMetaStrings);
    Editor.log("meta", plistMetaData);
    return plistMetaData

  },
  /**
   *  发消息给panel线程
   */
  sendPanel() {
    // 发消息给panel线程
    Editor.log('发消息给panel线程');
    Editor.Ipc.sendToPanel("zzw_quate.panel.partial", "resetCkickBtn", (error) => {
      Editor.log('逻辑执行完后按钮重置状态!', error);
      this.resetCkickBtn();
    });
  },
};